#pragma once
#include <vector>
#include <thread>
#include <mutex>
#include <atomic>
#include<functional>
#include <any>
#include"../common/service_status.h"
#include<event2/event.h>
#include <unordered_map>
#include <future>
#include "event.h"
class EventLoop : public ServiceStatus {

//    typedef std::function<void()> Functor;
public:
    class EventData {
    public:
        EventLoop* target;
        std::unique_ptr<Event> event;
    };
    //static std::unordered_map<EventLoop*,>
    EventLoop();
    void stopAndDelete();
    virtual ~EventLoop();
    void stamp(Event* ev);
    virtual bool event(std::unique_ptr<Event> ev)=0;
    static void replyEvent(std::unique_ptr<Event> ev);
   static void postEvent(EventLoop* to, std::unique_ptr<Event> ev, EventLoop* from=nullptr);
    // @brief Run the IO Event driving loop forever
    // @note It must be called in the IO Event thread
    //void Run();

    // @brief Stop the event loop
  //  void Stop();

    // @brief Reinitialize some data fields after a fork
   // void AfterFork();

  //  InvokeTimerPtr RunAfter(double delay_ms, const Functor& f);
  //  InvokeTimerPtr RunAfter(Duration delay, const Functor& f);

    // RunEvery executes Functor f every period interval time.
 //   InvokeTimerPtr RunEvery(Duration interval, const Functor& f);

 //   void RunInLoop(const Functor& handler);
 //   void QueueInLoop(const Functor& handler);

   // InvokeTimerPtr RunAfter(double delay_ms, Functor&& f);
   // InvokeTimerPtr RunAfter(Duration delay, Functor&& f);

    // RunEvery executes Functor f every period interval time.
  //  InvokeTimerPtr RunEvery(Duration interval, Functor&& f);

  //  void RunInLoop(Functor&& handler);
   // void QueueInLoop(Functor&& handler);

    // Getter and Setter
    EventLoop* start();
    struct event_base* eventDispatcher() {
        return eventbase_;
    }

    static void caller(int,short,void* data);
    const std::thread::id& tid() const {
        return tid_;
    }
private:
   // void Init();

private:
    struct event_base* eventbase_;

    //std::mutex mutex_;
    std::future<void> future_;
    std::thread::id tid_;

};